package ee.ut.cs.mc.madp.p2pdivider.fragment;

import java.util.ArrayList;
import java.util.Arrays;

import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.Toast;
import ee.ut.cs.mc.madp.p2pdivider.BaseDividerActivity;
import ee.ut.cs.mc.madp.p2pdivider.R;
import ee.ut.cs.mc.madp.p2pdivider.adapter.DeviceGridAdapter;
import ee.ut.cs.mc.madp.p2pdivider.adapter.DeviceListAdapter;

/**
 * Fragment that contains functionality related to setup of devices
 * 
 * @author Kaarel Jõgeva
 */
public class DevicesFragment extends Fragment implements PeerListListener, ConnectionInfoListener {

    final private static String TAG = DevicesFragment.class.getSimpleName();
    private final WifiP2pDevice[] layout = new WifiP2pDevice[4];
    private DeviceGridAdapter adapter;
    private WifiP2pInfo info;

    private View view;

    public DevicesFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.activity_devices, null);

        // init list
        ListView list = (ListView) view.findViewById(R.id.deviceList);
        list.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, new String[] { getString(R.string.no_devices) }));

        // Init device layout
        GridView layoutGrid = (GridView) view.findViewById(R.id.devicePositions);
        adapter = new DeviceGridAdapter(getActivity().getApplicationContext(), R.layout.view_device_grid_cell, this, layout);
        layoutGrid.setAdapter(adapter);

        // First run
        WifiP2pDevice host = new WifiP2pDevice();
        if (adapter.getPosition(host) < 0) {
            onDeviceConnect(host); // Add the host entry
        }

        return view;
    }

    @Override
    public void onPeersAvailable(WifiP2pDeviceList peers) {
        // TODO Populate the list
        Log.d(TAG, Arrays.deepToString(peers.getDeviceList().toArray()));
        ListView list = (ListView) view.findViewById(R.id.deviceList);
        list.setAdapter(new DeviceListAdapter(getActivity(), android.R.layout.simple_list_item_1, this, new ArrayList<WifiP2pDevice>(peers
                .getDeviceList())));
    }

    @Override
    public void onConnectionInfoAvailable(WifiP2pInfo info) {
        Log.d(TAG, "onConnectionInfoAvailable: \n" + info.toString());
        this.info = info;
    }

    public void updateThisDevice(WifiP2pDevice parcelableExtra) {
        // TODO remove the info or update data
        Log.d(TAG, "updateThisDevice: \n" + parcelableExtra.toString());
    }


    public void onDeviceConnect(WifiP2pDevice device) {
        Log.d(TAG, "Connected with device " + device.deviceName);
        // Add device to the collection and let adapter update the UI
        int index = 0;
        for (int i = 0; i < layout.length; i++) {
            if (layout[i] == null) {
                layout[i] = device;
                index = i;
                break;
            }
        }
        adapter.insert(device, index);
    }

    public void onDeviceConnectFailed(WifiP2pDevice device) {
        Toast.makeText(getActivity(), getString(R.string.err_device_connect, device.deviceName), Toast.LENGTH_SHORT).show();
    }

    public void onDeviceConnectPending(WifiP2pDevice device) {
        Toast.makeText(getActivity(), getString(R.string.info_device_connect_pending, device.deviceName), Toast.LENGTH_SHORT).show();
    }

    public void removeDevice(WifiP2pDevice device) {
        for (int i = 0; i < layout.length; i++) {
            WifiP2pDevice dev = layout[i];
            if (dev != null && dev.equals(device)) {
                layout[i] = null;
                break;
            }
        }
        adapter.remove(device);
    }

    public void connectTo(final WifiP2pDevice device) {
        switch (device.status) {
        case WifiP2pDevice.AVAILABLE:
            WifiP2pConfig config = new WifiP2pConfig();
            config.groupOwnerIntent = 15; // We must be the owner of the group to capture handshakes?
            config.deviceAddress = device.deviceAddress;
            BaseDividerActivity dividerActivity = (BaseDividerActivity) getActivity();
            dividerActivity.getManager().connect(dividerActivity.getChannel(), config, new ActionListener() {

                @Override
                public void onSuccess() {
                    onDeviceConnect(device);
                }

                @Override
                public void onFailure(int reason) {
                    onDeviceConnectFailed(device);
                }
            });

            break;
        case WifiP2pDevice.CONNECTED:
            onDeviceConnect(device);
            break;
        case WifiP2pDevice.INVITED:
            onDeviceConnectPending(device);
            break;
        case WifiP2pDevice.FAILED:
        case WifiP2pDevice.UNAVAILABLE:
            onDeviceConnectFailed(device);
            break;
        }
    }

    public void disconnectFrom(WifiP2pDevice device) {
        removeDevice(device);

    }

    public WifiP2pDevice[] getSelectedDevices() {
        int deviceCount = adapter.getCount();
        WifiP2pDevice[] devices = new WifiP2pDevice[deviceCount];
        for (int i = 0; i < devices.length; i++) {
            devices[i] = adapter.getItem(i);
        }
        return devices;
    }

    public WifiP2pInfo getInfo() {
        return info;
    }

}